package com.mall.user.services;

import com.alibaba.fastjson.JSON;
import com.mall.user.ILoginService;
import com.mall.user.constants.SysRetCodeConstants;

import com.mall.user.converter.MemberConverter;
import com.mall.user.dal.entitys.Member;

import com.mall.user.dal.entitys.UserToken;
import com.mall.user.dal.entitys.UserVerify;
import com.mall.user.dal.persistence.MemberMapper;
import com.mall.user.dal.persistence.UserVerifyMapper;
import com.mall.user.dto.*;
import com.mall.user.utils.EncryptPasswordUtil;
import com.mall.user.utils.ExceptionProcessorUtils;
import com.mall.user.utils.JwtTokenUtils;
import com.mall.user.utils.RegisterValidatorUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;

import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.UUID;

/**
 * @Author: dhy
 * @Date: 2021/1/22 19:12
 * @Description:
 */
@Slf4j
@Component
@Service
public class ILoginServiceImpl implements ILoginService {
    @Autowired
    MemberMapper memberMapper;
    @Autowired
    MemberConverter memberConverter;
    @Autowired
    UserVerifyMapper userVerifyMapper;
    @Autowired
    JavaMailSender javaMailSender;
    @Override
    public CheckAuthResponse validToken(CheckAuthRequest checkAuthRequest) {
        CheckAuthResponse response = new CheckAuthResponse();
        try {
            checkAuthRequest.requestCheck();
            //解码
            String freeJwt = JwtTokenUtils.builder().token(checkAuthRequest.getToken()).build().freeJwt();
            response.setUserinfo(freeJwt);
            response.setCode(SysRetCodeConstants.SUCCESS.getCode());
            response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("ILoginServiceImpl.validToken occur Exception :" +e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
        }
        return response;

    }

    @Override
    public UserLoginResponse validUserLogin(UserLoginRequest userLoginRequest) {
        UserLoginResponse userLoginResponse = new UserLoginResponse();

        //查询用户是否存在,密码是否正确
        Member user = null;
        try {
            //参数校验
            userLoginRequest.requestCheck();

            Member member = new Member();
            String userName = userLoginRequest.getUserName();
            member.setUsername(userName);
            String password = userLoginRequest.getPassword();
            //密码加密
            String encryptPassword = EncryptPasswordUtil.getEncryptPassword(password);
            member.setPassword(encryptPassword);
            user = memberMapper.selectOne(member);
            if (user == null) {
                //验证是否为激活过的邮箱登录
                Member member1 = new Member();
                member1.setEmail(userName);
                member1.setPassword(encryptPassword);
                member1.setIsVerified("Y");
                Member user1 = memberMapper.selectOne(member1);
                if (user1 != null) {
                    //为邮箱登录
                    userLoginResponse = getUserLoginResponse(user1);
                } else {
                    //用户名或密码不正确
                    userLoginResponse.setCode(SysRetCodeConstants.USERORPASSWORD_ERRROR.getCode());
                    userLoginResponse.setMsg(SysRetCodeConstants.USERORPASSWORD_ERRROR.getMessage());
                }

            }else {
                //查询邮箱是否验证过
                if (user.getIsVerified().equals("N")) {
                    //用户名尚未激活
                    userLoginResponse.setCode(SysRetCodeConstants.USER_ISVERFIED_ERROR.getCode());
                    userLoginResponse.setMsg(SysRetCodeConstants.USER_ISVERFIED_ERROR.getMessage());
                } else if (user.getIsVerified().equals("Y")) {
                    //用户已激活
                    userLoginResponse = getUserLoginResponse(user);
                }
            }
        } catch (Exception e) {
            log.error("ILoginServiceImpl.validUserLogin Occur Exception :"+e);
            ExceptionProcessorUtils.wrapperHandlerException(userLoginResponse,e);
        }
        return userLoginResponse;
    }

    /**
     * 登录的请求参数封装,并且生成token
     * @param user
     * @return
     */
    private UserLoginResponse getUserLoginResponse(Member user) {
        UserLoginResponse userLoginResponse;
        userLoginResponse = memberConverter.member2Login(user);
        userLoginResponse.setCode(SysRetCodeConstants.SUCCESS.getCode());
        userLoginResponse.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
        //根据 json类 生成一个token
        UserToken userToken = new UserToken();
        userToken.setUid(user.getId());
        userToken.setUName(user.getUsername());
        String json =  JSON.toJSONString(userToken);
        String token = JwtTokenUtils.builder().msg(json).build().creatJwtToken();
        userLoginResponse.setToken(token);
        return userLoginResponse;
    }

    @Override
    public UserLoginInfoResponse returnUserInfo(String userInfo) {
        UserLoginInfoResponse response = new UserLoginInfoResponse();
        try {
            Member member = new Member();
            member.setUsername(userInfo);
            Member user = memberMapper.selectOne(member);
            response.setId(user.getId());
            response.setFile(user.getFile());
            response.setCode(SysRetCodeConstants.SUCCESS.getCode());
            response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("ILoginServiceImpl.returnUserInfo Occur Exception :"+e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
        }
        return response;

    }

    @Override
    @Transactional
    public UserRegisterResponse userRegister(UserRegisterRequest userRegisterRequest) {
        UserRegisterResponse userRegisterResponse = new UserRegisterResponse();
        try {
            //判通
            userRegisterRequest.requestCheck();
            //用户名,密码,邮箱正则校验
            String userName = userRegisterRequest.getUserName();
            String userPwd = userRegisterRequest.getUserPwd();
            String email = userRegisterRequest.getEmail();
            String validate = RegisterValidatorUtil.registerValidate(userName, userPwd, email);
            if (validate != null) {
                //正则校验不通过
                userRegisterResponse.setCode("003004");
                userRegisterResponse.setMsg(validate);
                return userRegisterResponse;
            }
            //判断用户名是否存在
            Member member = new Member();
            member.setUsername(userName);
            Member user1 = memberMapper.selectOne(member);
            if (user1 != null) {
                //用户名存在
                userRegisterResponse.setCode(SysRetCodeConstants.USERNAME_ALREADY_EXISTS.getCode());
                userRegisterResponse.setMsg(SysRetCodeConstants.USERNAME_ALREADY_EXISTS.getMessage());
                return userRegisterResponse;
            }
            //判断邮箱是否存在
            Member member2 = new Member();
            member2.setEmail(email);
            Member user2 = memberMapper.selectOne(member2);
            if (user2 != null) {
                //邮箱已存在
                userRegisterResponse.setCode(SysRetCodeConstants.USEREMAIL_ALREADY_EXISTS.getCode());
                userRegisterResponse.setMsg(SysRetCodeConstants.USEREMAIL_ALREADY_EXISTS.getMessage());
                return userRegisterResponse;
            }
            //添加用户信息进数据库,并发送邮件
            userVerify(userName,userPwd,email);

            userRegisterResponse.setCode(SysRetCodeConstants.SUCCESS.getCode());
            userRegisterResponse.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("ILoginServiceImpl.userRegister Occur Exception :"+e);
            ExceptionProcessorUtils.wrapperHandlerException(userRegisterResponse,e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return userRegisterResponse;
    }

    /**
     * 用户注册信息录入,并发送邮箱验证,失败则回滚
     * @param userName
     * @param userPwd
     * @param email
     */

    @Transactional(rollbackFor = Exception.class)
    public void userVerify(String userName, String userPwd, String email) {


            Member member3 = new Member();
            member3.setUsername(userName);
            //密码加密
            String encryptPassword = EncryptPasswordUtil.getEncryptPassword(userPwd);
            member3.setPassword(encryptPassword);
            member3.setEmail(email);
            member3.setCreated(new Date());
            member3.setUpdated(new Date());
            memberMapper.insertSelective(member3);


            //生成uuid
            String uuid = UUID.randomUUID().toString().replaceAll("-","");
            UserVerify userVerify = new UserVerify();
            userVerify.setUsername(userName);
            userVerify.setUuid(uuid);
            userVerify.setRegisterDate(new Date());
            userVerify.setIsVerify("N");
            userVerify.setIsExpire("N");
            //添加用户注册信息到用户注册表
            userVerifyMapper.insert(userVerify);
            //向用户发送邮箱验证
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom("donghanyu118@163.com");
            message.setTo(email);
            message.setSubject("mall注册邮箱校验");
            //TODO 目前写死了url ,后面可以完善
            message.setText("http://192.168.5.56:8080/user/verify?userName="+userName+"&uuid="+uuid);
            javaMailSender.send(message);
    }

    @Override
    @Transactional
    public UserVerifyResponse emailVerify(UserVerifyRequest userVerifyRequest) {
        UserVerifyResponse response = new UserVerifyResponse();
        try {
            userVerifyRequest.requestCheck();
            String userName = userVerifyRequest.getUserName();
            String uuid = userVerifyRequest.getUuid();
            //判断用户是否存在
            UserVerify userVerify = new UserVerify();
            userVerify.setUuid(uuid);
            userVerify.setUsername(userName);
            UserVerify userVerify1 = userVerifyMapper.selectOne(userVerify);
            if (userVerify1 == null) {
                response.setCode(SysRetCodeConstants.VERIFY_NOT_EXIST.getCode());
                response.setMsg(SysRetCodeConstants.VERIFY_NOT_EXIST.getMessage());
                return response;
            }
            //判断用户是否已激活
            Member member2 = new Member();
            member2.setUsername(userName);
            member2.setIsVerified("Y");
            int count = memberMapper.selectCount(member2);
            if (count != 0) {
                response.setCode(SysRetCodeConstants.VERIFY_ERROR.getCode());
                response.setMsg(SysRetCodeConstants.VERIFY_ERROR.getMessage());
                return response;
            }
            //修改激活状态
            updateVerifyStatus(userName);

            response.setCode(SysRetCodeConstants.SUCCESS.getCode());
            response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("ILoginServiceImpl.emailVerify Occur Exception :"+e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return response;
    }

    /**
     * 修改激活状态
     * @param userName
     */
    @Transactional
    public void updateVerifyStatus(String userName) {
        Example example = new Example(UserVerify.class);
        example.createCriteria().andEqualTo("username",userName);
        UserVerify userVerify = new UserVerify();
        userVerify.setIsVerify("Y");
        userVerifyMapper.updateByExampleSelective(userVerify,example);
        Example example1 = new Example(Member.class);
        example1.createCriteria().andEqualTo("username",userName);
        Member member = new Member();
        member.setIsVerified("Y");
        memberMapper.updateByExampleSelective(member,example1);
    }

}
